package config

import (
	"encoding/json"
	"fmt"
	"gitee.com/jjawesomejj/awesome-util/echo"
	"gitee.com/jjawesomejj/awesome-util/helper/commonhelper"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
)

var configJson map[string]interface{}
var configPath string = CurrentFile()
var configLocalPath string = configPath + "/config-local.json"
var IS_WRITE_TO_FILE = true

func SetIsWriteToFile(isWrite bool) {
	IS_WRITE_TO_FILE = isWrite
}

func InitConfig() (jsonConfig1 map[string]interface{}) {
	if configJson != nil {
		return configJson
	}
	if IS_WRITE_TO_FILE == false {
		configJson = make(map[string]interface{})
		return configJson
	}
	configPath = commonhelper.GetCurrentRunningPath()
	initTemplate()
	if commonhelper.CheckFileIsExist(configLocalPath) == false {
		commonhelper.WriteFile(configLocalPath, commonhelper.JsonEncode(make(map[string]string)), 0777)
	}
	data, err := ioutil.ReadFile(configPath + "/config.json")
	if err != nil {
		panic(err.Error())
	}
	jsonConfig := make(map[string]interface{})
	err1 := json.Unmarshal(data, &jsonConfig)
	if err1 != nil {
		panic(err1.Error())
	}

	configJson = jsonConfig
	configJson["configDir"] = configPath
	return jsonConfig
}

func PrintConfig() {
	InitConfig()
	fmt.Println(commonhelper.FormatJsonStringfy(configJson))
}
func CurrentFile() string {
	exe, err := os.Executable()
	if err != nil {
		panic(err)
	}
	return filepath.Dir(exe)
}
func GetConfigByKey(keys string, fun ...func() interface{}) interface{} {
	config := InitConfig()
	list := strings.Split(keys, ".")
	for index, i := range list {
		if index == len(list)-1 {
			value, ok := config[i]
			if ok {
				return value
			}
			if len(fun) == 0 {
				fmt.Println(fmt.Sprintf("require key %s not found", keys))
				os.Exit(-1)
			}
			if fun[0] != nil {
				return fun[0]()
			}
			return nil
		}
		if _, ok := config[i]; !ok {
			return nil
		}
		config = config[i].(map[string]interface{})
	}
	return config
}
func GetConfigByKeyWithAlias(keys string) interface{} {
	config := InitConfig()
	list := strings.Split(keys, ".")
	list[len(list)-1] = "Alias" + list[len(list)-1]
	for index, i := range list {
		if index == len(list)-1 {
			if config[i] != nil {
				return config[i]
			} else {
				return config[strings.Replace(i, "Alias", "", 1)]
			}

		}
		config = config[i].(map[string]interface{})
	}
	return config
}

func SetConfigByKey(key string, value interface{}, shouldStore ...bool) {
	InitConfig()
	list := strings.Split(key, ".")
	if len(list) > 1 {
		if GetConfigByKey(key) == nil {
			return
		} else {
			localConfig := configJson
			for index, itemKey := range list {
				if index == len(list)-1 {
					localConfig[itemKey] = value
				} else {
					localConfig = localConfig[itemKey].(map[string]interface{})
				}
			}
		}
	} else {
		configJson[key] = value
		//jsonByte,_ :=json.Marshal(configJson)
	}
	if !IS_WRITE_TO_FILE {
		return
	}
	if len(shouldStore) == 0 || shouldStore[0] {
		jsonString := commonhelper.FormatJsonStringfy(configJson)
		newPath := configPath + "/config.json"
		commonhelper.WriteFile(newPath, jsonString, 0777)
	}
}

func GetConfigByPath(path string) map[string]interface{} {
	data, err := ioutil.ReadFile(path)
	if err != nil {
		panic(err.Error())
	}
	return commonhelper.JsonDecode(string(data)).(map[string]interface{})
}
func MergeConfig(paths ...string) {
	InitConfig()
	for _, path := range paths {
		for key, params := range GetConfigByPath(path) {
			configJson[key] = params
		}
	}
}
func initTemplate() {
	if !IS_WRITE_TO_FILE {
		return
	}
	configPath += "/project-config/"
	mainConfigPath := configPath + "/config.json"
	if commonhelper.CheckFileIsExist(mainConfigPath) == false {
		template := `
{
"database": {
			"database": "awesometask",
			"driver": "mysql",
			"host": "awesomeTask-mysql",
			"password": "awesomeTaskpublic",
			"port": "3306",
			"user": "root"
		}
}
`
		commonhelper.WriteFile(mainConfigPath, template, 0777)
	}
	localConfigPath := configPath + "/config-local.json"
	localTemplate := `{
}
`
	if commonhelper.CheckFileIsExist(localConfigPath) == false {
		commonhelper.WriteFile(localConfigPath, localTemplate, 0777)
	}
}
func HandleCommandLineSetToConfig() {
	params := echo.GetCmdInputParams()
	for key, value := range params {
		SetConfigByKey(key, value)
	}
}
